home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / newsgroups / misc.20000824-20010305 / 000358_news@columbia.edu _Fri Feb 23 20:16:29 2001.msg < prev    next >
Internet Message Format  |  2020-01-01  |  15KB

  1. Return-Path: <news@columbia.edu>
  2. Received: from watsun.cc.columbia.edu (watsun.cc.columbia.edu [128.59.39.2])
  3.     by uhaligani.cc.columbia.edu (8.9.3/8.9.3) with ESMTP id UAA09463
  4.     for <kermit.misc@cpunix.cc.columbia.edu>; Fri, 23 Feb 2001 20:16:29 -0500 (EST)
  5. Received: from newsmaster.cc.columbia.edu (newsmaster.cc.columbia.edu [128.59.59.30])
  6.     by watsun.cc.columbia.edu (8.8.5/8.8.5) with ESMTP id UAA28456
  7.     for <kermit.misc@watsun.cc.columbia.edu>; Fri, 23 Feb 2001 20:16:28 -0500 (EST)
  8. Received: (from news@localhost)
  9.     by newsmaster.cc.columbia.edu (8.9.3/8.9.3) id UAA08309
  10.     for kermit.misc@watsun.cc.columbia.edu; Fri, 23 Feb 2001 20:02:03 -0500 (EST)
  11. X-Authentication-Warning: newsmaster.cc.columbia.edu: news set sender to <news> using -f
  12. From: fdc@columbia.edu (Frank da Cruz)
  13. Subject: Modem Scripting Tutorial
  14. Date: 24 Feb 2001 01:02:02 GMT
  15. Organization: Columbia University
  16. Message-ID: <97716a$83i$1@newsmaster.cc.columbia.edu>
  17. To: kermit.misc@columbia.edu
  18.  
  19.  
  20. It's been a while since scripting tutorials have been posted here, but
  21. with C-Kermit 7.1 nearing release, with all its new scripting features,
  22. now seems like a good time to resurrect the practice.
  23.  
  24. Does your organization have a big modem pool?  Of course (like any other
  25. big university) ours has has a pool of many hundreds of lines.  As you
  26. know, phone lines aren't cheap so the annual cost of running a big modem
  27. pool is painful.  Yet, even in this age of DSL and cable modems, the demand
  28. for modems never stops increasing, and therefore so do the complaints about
  29. busy signals, and the pressure to increase the capacity, and the
  30. counterpressure to contain contain costs.  (Eventually some day every room
  31. will have an Internet jack and modems will have the same historical status
  32. as card punches and Teletypes, but that's another discussion -- for now DSL
  33. in the home is often not available, usually has a long wait when it is, and
  34. it's expensive).
  35.  
  36. One consequence of all this is the need to monitor and test the modem pool
  37. to make sure it's working at its best -- no broken or poorly-performing
  38. lines or servers -- plus the degree to which it is available, i.e. the
  39. answer-to-call ratio.  There's a script for doing this in the Kermit script
  40. library, but it's undergone quite a few refinements in recent months as we
  41. reconfigure our modem pool, change telephone service providers, etc, and
  42. many of the refinements nicely illustrate new features of C-Kermit 7.1 (and
  43. the forthcoming next release of Kermit 95).
  44.  
  45.   http://www.columbia.edu/kermit/ck71.html
  46.  
  47. The script is given a list of phone numbers and a list of terminal-server
  48. names.  Each list can have one or more items.  Obviously the script also
  49. needs to know the details of the calling computer: serial device and/or
  50. modem name, speed, etc.  The script prompts for password (because it's a bad
  51. idea to store passwords in files) and runs in a loop, performing the
  52. following actions:
  53.  
  54.  1. Calls the next phone number from the list (which is circular).
  55.     If the call is not answered or the line is busy, the appropriate
  56.     error is logged and this step is repeated.
  57.  
  58.  2. Gets the terminal server prompt, gives any necessary configuration
  59.     commands to the terminal server, and then requests a Telnet connection
  60.     to a host computer.  If this fails, an error is logged and the script
  61.     hangs up and goes back to step 1.  If the terminal server announces
  62.     its name and the line number for the call, these are captured.
  63.  
  64.  3. Logs in to the host computer.
  65.  
  66.  4. Starts a Kermit server on the host, uploads a 100K precompressed
  67.     file and downloads the same file.
  68.  
  69.  6. Says BYE to the Kermit server, closing the connection.
  70.  
  71.  7. Gets statistics about the call from the modem, including block-error
  72.     and retrain counts and final session modulation speeds.
  73.  
  74.  5. Writes a log record showing the date and time, phone number, 
  75.     terminal server name and line, initial connection speed. final input
  76.     and output modulation speeds, block-error and retrain counts, and
  77.     the upload and download throughput in characters per second.
  78.  
  79. Here is bit of a log:
  80.  
  81. Date  Time  Number    Line       Speed  Speed-After  Blers Retr Upload  Dnload
  82. ----------  -------   --------   -----  -----------  ----- ---- ------  ------
  83. 02/22 0905  5551234   ccts5:080  49333  50666/28800      0    0   2951    5184
  84. 02/22 0907  5551235   ccts3:002  49333  49333/31200      1    0   3255    5143
  85. 02/22 0909  5551236   ccts2:096  49333  49333/31200      6    0   3243    5031
  86. 02/22 0911  5551237   ccts5:051  49333  50666/28800      1    0   3002    5220
  87. 02/22 0913  5551238   ccts5:069  49333  50666/28800      0    0   3008    5234
  88.  
  89. In this case we're calling from a V.90 (56K) modem, which, as you know, 
  90. supports higher speeds in the incoming direction than the outgoing.  The
  91. terminal server names are ccts2, ccts3, etc; the combination of server name
  92. and line number specify a particular telephone circuit and modem.
  93.  
  94. Naturally, every imaginable kind of error is caught and logged:
  95.  
  96. 02/22 0917  5551240   ccts3:076  49333  49333/31200      5    0   3217    5068
  97. 02/22 0919  5551241   ccts5:112  49333      UNKNOWN    UNK  UNK   3010    5215
  98. 02/22 1055  5551241   ccts4:UNK  31200      UNKNOWN    UNK  UNK FAILED  FAILED
  99. 02/22 1119  5551243  FAILED: "BUSY"
  100. 02/22 1509  5551244  FAILED: "NO CARRIER"
  101. 02/22 1509  5551245   ccts5:183  49333  50666/31200      1    0   2925    5201
  102.  
  103. The script can be halted between calls by the operator from the keyboard,
  104. but you don't need to halt it to get at the log, which is opened and closed
  105. around each write so it can be examined, copied, uploaded, or whatever on
  106. platforms that might not allow shared access to open files.
  107.  
  108. The log format is such that headings and so forth can be separated out
  109. (in UNIX) with:
  110.  
  111.   grep ^[0-9] modem.log > entries
  112.  
  113. leaving one line per call:
  114.  
  115.   wc -l entries                   # number of calls
  116.   grep -v FAILED entries | wc -l  # number that were answered
  117.  
  118. The ratio of these two numbers gives the answer-to-call ration.  (C-Kermit
  119. 7.1 also has its own internal GREP and line-counting commands in case
  120. you're not using UNIX.)
  121.  
  122. A log of successful calls can be sorted in various ways because the columns
  123. are fixed.  For example, sorting on the "Line" column puts multiple calls
  124. to the same number together.  The numeric data can be analyzed
  125. statistically too.  For example, you can get the minimum, maximum, and mean
  126. upload or download speed and you can correlate it with telephone or line
  127. number to see (for example) if certain lines, terminal servers, or phone
  128. numbers perform better or worse than others over many calls (this would
  129. also jump out at you when eyeballing a sorted log).
  130.  
  131. The updated modem-test script is here:
  132.  
  133.   ftp://kermit.columbia.edu/kermit/scripts/ckermit/modemtest2
  134.  
  135. Let's look at a few pieces of it:
  136.  
  137.   dcl \&n[] = 5551234 5551235 5551236 5551237 5551238 5551239 5551240 -
  138.               5551241 5551242 5551243 5551244 5551245 5551246 5551247
  139.  
  140.   dcl \&p[] = ccts1 ccts2 ccts3 ccts4 ccts5 ccts6
  141.  
  142. This declares an array \&n[] and loads it with 16 phone numbers, and another
  143. array \&p[], loading it with six terminal-server names.  To change the
  144. script to use different lists of numbers and names requires changing only
  145. these two statements -- everything else adjusts itself automatically.
  146.  
  147. The terminal-server prompt turns out to be the terminal-server name followed
  148. by a ">" character, such as "ccts3>", so we construct a parallel array,
  149. \&q[], of prompts:
  150.  
  151.   dcl \&q[\fdim(&p)]                  
  152.   for \%i 1 \fdim(&p) 1 {
  153.     .\&q[\%i] := \&p[\%i]>
  154.   }
  155.  
  156. The size of this array must be included in its declaration, since we are not
  157. initializing it in the declaration.  But unlike in other languages (such as
  158. C), the size need not be a constant.  In this case we say that the size is
  159. the "dimension" (size) of the array \&p[].  Then we loop through the new
  160. array, making the appropriate assignments.
  161.  
  162. Here's where we dial, illustrating (a) how we dial a number from the array;
  163. (b) how we handle failures based on Kermit's \v(dialstatus) variable (the
  164. \v(dialresult) variable is the modem's call-result message string):
  165.  
  166.   dial \&n[\%i]  ; \%i is the loop variable.
  167.   if fail {
  168.       switch \v(dialstatus) {
  169.     :8, logrecord {FAILED: Timed out}, break
  170.     :9, logrecord {FAILED: User canceled}, stop
  171.     :10, logrecord {FAILED: Modem not ready}, break
  172.     :default, logrecord {FAILED: "\v(dialresult)"}, break
  173.       }
  174.       continue
  175.   }
  176.  
  177. The terminal servers in question are Ciscos.  Upon connection you can
  178. either send PPP negotiation data or else request a command prompt by
  179. sending a carriage return.  The script sends a carriage return.  The server
  180. prints a screenful of text and then the prompt:
  181.  
  182.   ccts4 line 17
  183.  
  184.   Welcome to blah blah blah
  185.   blah blah blah
  186.   blah blah blah blah
  187.  
  188.   ccts4>
  189.  
  190. The text might or might not contain a line like this:
  191.  
  192.   ccts4 line 17
  193.  
  194. If it does, we need to pick up the line (port) number, but if it doesn't,
  195. we don't want to get stuck waiting for it.  So instead, we scoop up
  196. everything up to and including the prompt:
  197.  
  198.   clear input                  ; Clear the INPUT buffer
  199.   .\%x := 0                    ; (explained below)
  200.   for \%j 1 10 1 {             ; Try 10 times to get terminal server herald
  201.       output \13               ; Send Carriage Return (ASCII 13)
  202.       minput 10 \fjoin(&q,,2)  ; Look for any of the prompts
  203.       if success break         ; Quit this loop if we get one
  204.   }
  205.   if > \%j 10 {                ; This means we didn't get one.
  206.       logrecord {FAILED: No terminal server prompt}
  207.       continue                 ; Go make another call.
  208.   }
  209.  
  210. The magic command in this section is:
  211.  
  212.   minput 10 \fjoin(&q,,2)
  213.  
  214. The function \fjoin() is new to C-Kermit 7.1.  It replaces itself with
  215. a text string consisting of all the elements of the given array, separated
  216. (in this case) by spaces (the "2" is a formatting code).  Therefore, this
  217. statement is equivalent to:
  218.  
  219.   minput 10 ccts1> ccts2> ccts3> ccts4> ccts5> ccts6>
  220.  
  221. This is not simply a notational convenience.  It's one of the features that
  222. allows our script to be table-driven, in the sense that we only have to
  223. change the array initialization to make the script use different server
  224. names or phone numbers, and even different numbers of them, without having
  225. to change other lines in the script, such as the MINPUT that looks for all
  226. the possible prompts.
  227.  
  228. If the MINPUT command succeeded, we have the entire output of the terminal
  229. server in our \v(input) variable.  Now we can scan it for the line-number
  230. text:
  231.  
  232.   .tmp := \v(input)  ; Copy the \v(input) variable
  233.   .\%x = \v(minput)  ; The item that MINPUT matched (1, 2, 3, ...)
  234.  
  235. The next statement searches for the line-number message.  \&p[\%x] is the
  236. name of this server, corresponding to the prompt.  So, for example, if the
  237. prompt was "ccts4>", the server name is "ccts4" and this statement searches
  238. the text we just read for the string "ccts4 line ".
  239.  
  240.   .\%y = \findex({\&p[\%x] line },\m(tmp))
  241.  
  242. Next, we initialize the tsport (terminal-server port) variable to "UNK" in
  243. the desired line was not found:
  244.  
  245.   .tsport = UNK
  246.  
  247. Then if the "ccts4 line " string was found, we use another function,
  248. \fword(), to get the third "word" from the string that starts with "ccts4
  249. line ".  This is the line number.  Then we left-pad (\flpad()) it with 0's
  250. so it is exactly 3 digits:
  251.  
  252.   if > \%y 0 {
  253.     .tsport := \flpad(\fword(\s(tmp[\%y]),3),3,0)
  254.   }
  255.  
  256. Now we know the server name and the port number:
  257.  
  258.   .tsport := \&p[\%x]:\m(tsport)
  259.  
  260. which, continuing with our example, becomes:
  261.  
  262.   ccts4:017
  263.  
  264. The rest is fairly straightforward: the regular OUTPUT / INPUT / IF FAIL
  265. sequence familiar to all Kermit script writers, to accomplish login,
  266. starting the Kermit program on the far end, transferring files, and logging
  267. out.  There is one new feature in the data-transfer phase that puts some
  268. status information in the file-transfer display:
  269.  
  270.   SET TRANSFER MESSAGE text
  271.  
  272. in which the text can contain variables.  In this case it's used to show
  273. the call sequence number, the phone number, the terminal server name and
  274. port, and the time the transfer started (so you can easily tell if it's
  275. stuck):
  276.  
  277.   set xfer message \m(seq): \v(dialnumber) (\m(tsport)) \v(time)
  278.  
  279. e.g.
  280.  
  281.   Last Message: 712: 5554321 (ccts3:020) 16:02:56
  282.  
  283. After logout comes another interesting part, where we query the modem for
  284. statistics and capture them.  Of course the details depend on the modem.
  285. For US Robotics modems we "output ATI6\13" and then parse the results
  286. as follows:
  287.  
  288.   set flag off
  289.   while not flag {
  290.      minput 10  Blers  Retrains  Speed  OK
  291.      switch \v(minput) {
  292.        :1, clear input, input 2 \10, .blers := \fword(\v(input),1), break
  293.        :2, clear input, input 2 \10, .retrains := \fword(\v(input),5), break
  294.        :3, clear input, input 2 \10, .ospeed := \fword(\v(input),1,,/), break
  295.        :4, set flag on, break
  296.      }
  297.   }
  298.  
  299. In other words, we look for any of "Blers", "Retrains", "Speed", and "OK"
  300. (which terminates the report).  If we get OK, we're done.  Otherwise we
  301. read the rest of the line ("input 2 \10", i.e. read up to a linefeed) and
  302. then use \fword() to extract the desired word.
  303.  
  304. The script requires about 2 minutes per call, so if all goes well it
  305. collects about 720 records per day, using a 100K test file and calling a
  306. 56K modem pool.  It's best to collect several samples per server port,
  307. which could take a day or two or more, depending on the size of your pool
  308. and its hunt strategy.
  309.  
  310. Finally, obtaining statistics from the results is easier than ever
  311. using C-Kermit 7.1's new floating-point arithmetic and S-Expression syntax:
  312.  
  313.   ftp://kermit.columbia.edu/kermit/scripts/ckermit/stats
  314.  
  315. All we need to do is filter out the error records, as shown at the top,
  316. and then use UNIX 'cut' to isolate the desired two columns of numbers.
  317. If the servername:port column is one of them, we can simply filter out
  318. the non-numeric characters, so (for example) ccts4:017 becomes 4017.
  319. Records that have ccts4:UNK are discarded completely since we don't know
  320. the port number.
  321.  
  322. Here we get statistics for upload and download speed versus server:port:
  323.  
  324.   grep ^[0-9] modem.log | grep -v FAILED > tmp
  325.  
  326.   cut -c21-31,65-70 < tmp > up
  327.   cut -c21-31,72-78 < tmp > dn
  328.  
  329.   tr -d "[a-z:]" < up | grep -v UNK > up2
  330.   tr -d "[a-z:]" < dn | grep -v UNK > dn2
  331.  
  332.   stats up2
  333.   stats dn2
  334.  
  335. The last one ("stats dn2") prints something like this:
  336.  
  337.   Points: 382
  338.              X         Y
  339.   Miminum:           2001.00   1875.00
  340.   Maximum:           5192.00   5282.00
  341.   Mean:              3642.26   5016.66
  342.   Variance:       1811436.52 157155.99
  343.   Std Deviation:     1345.90    396.43
  344.  
  345.   Correlation coefficient:        0.12
  346.  
  347. - Frank